---
title: Remark NPM
description: Generate code blocks for package managers
---

## Usage

Add the remark plugin.

```ts tab="MDX Compiler"
import { compile } from '@mdx-js/mdx';
import { remarkNpm } from 'fumadocs-core/mdx-plugins';

await compile('...', {
  remarkPlugins: [remarkNpm],
});
```

```ts title="source.config.ts" tab="Fumadocs MDX"
import { defineConfig } from 'fumadocs-mdx/config';

export default defineConfig({
  mdxOptions: {
    remarkNpmOptions: {
      // it is enabled by default, customise it here
    },
  },
});
```

Define the required components:

```tsx tab="Custom" title="mdx-components.tsx"
import {
  CodeBlockTabs,
  CodeBlockTab,
  CodeBlockTabsList,
  CodeBlockTabsTrigger,
} from 'my-ui';
import type { MDXComponents } from 'mdx/types';

export function getMDXComponents(components?: MDXComponents): MDXComponents {
  return {
    CodeBlockTabs,
    CodeBlockTab,
    CodeBlockTabsList,
    CodeBlockTabsTrigger,
    ...components,
  };
}
```

```tsx tab="Fumadocs UI" title="mdx-components.tsx"
import defaultComponents from 'fumadocs-ui/mdx';
import type { MDXComponents } from 'mdx/types';

export function getMDXComponents(components?: MDXComponents): MDXComponents {
  return {
    // it's included by default in `defaultComponents`
    ...defaultComponents,
    ...components,
  };
}
```

| Component            |                                                 |
| -------------------- | ----------------------------------------------- |
| CodeBlockTabs        | Accepts a `defaultValue` prop for default value |
| CodeBlockTabsList    | N/A                                             |
| CodeBlockTab         | Accepts a `value` prop                          |
| CodeBlockTabsTrigger | Accepts a `value` prop                          |

### Input

Create code blocks with `npm` as language.

````mdx
```npm
npm i my-package
```

```npm
npm i my-package -D
```
````

### Output

The following structure should be generated by the plugin.

```mdx
<CodeBlockTabs defaultValue="npm">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">npm</CodeBlockTabsTrigger>
    <CodeBlockTabsTrigger value="pnpm">pnpm</CodeBlockTabsTrigger>
    <CodeBlockTabsTrigger value="yarn">yarn</CodeBlockTabsTrigger>
    <CodeBlockTabsTrigger value="bun">bun</CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">...</CodeBlockTab>
  <CodeBlockTab value="pnpm">...</CodeBlockTab>
  <CodeBlockTab value="yarn">...</CodeBlockTab>
  <CodeBlockTab value="bun">...</CodeBlockTab>
</CodeBlockTabs>
```

```npm
npm i my-package
```

### Persistent

When using with Fumadocs UI, you can enable persist the selected value with the `persist` option.

```ts title="source.config.ts" tab="Fumadocs MDX"
import { defineConfig } from 'fumadocs-mdx/config';

export default defineConfig({
  mdxOptions: {
    remarkNpmOptions: {
      persist: {
        id: 'package-manager',
      },
    },
  },
});
```

```ts tab="MDX Compiler"
import { compile } from '@mdx-js/mdx';
import { remarkNpm, type RemarkNpmOptions } from 'fumadocs-core/mdx-plugins';

const remarkNpmOptions: RemarkNpmOptions = {
  persist: {
    id: 'package-manager',
  },
};

await compile('...', {
  remarkPlugins: [[remarkNpm, remarkNpmOptions]],
});
```

This will generate a [`persist`](/docs/ui/components/tabs#persistent) prop to `<CodeBlockTabs />`.
